LL_FMAC_Init and LL_FMAC_DeInit APIs migration

The LL initialization and de-initialization functions previously available in the stm32tnxx_ll_fmac.c files within HAL1 are no longer present in HAL2. In HAL2, all LL C files ( stm32tnxx_ll_fmac.c) have been removed, leaving only the LL header files ( stm32tnxx_ll_fmac.h) that contain static inline functions.

If users need to initialize or de-initialize FMAC using the LL layer, they have two methods:

  • Utilize STM32CubeMX2 Code Generation: Rely on STM32CubeMX2 to generate code with the LL layer for FMAC initialization and de-initialization.

  • Replace manually the initialization and de-initialization functions : Replace the LL_FMAC_Init and LL_FMAC_DeInit functions manually with equivalent sequences using the static inline functions provided in the stm32tnxx_ll_fmac.h file, tailored to their specific configuration and requirements.

This approach ensures that the initialization and de-initialization sequences are precisely addressing the given use case based on the LL static inline functions provided in the stm32tnxx_ll_fmac.h header file. The sequences offer improved footprint optimization compared to the previous LL initialization functions found in stm32tnxx_ll_fmac.c.

Related concept: Remove stm32tnxx_ll_ppp.c files

Method 1: Utilize STM32CubeMX2 Code Generation

LL FMAC configuration panel

Create a new project with the STM32CubeMX2, then start the initialization and the main configuration.

Example Image

LL FMAC main features configuration

Configure the FMAC main features.

FMAC main feature configuration

LL FMAC advanced features configuration

Configure the advanced FMAC features.

FMAC advanced feature configuration

DMA configuration

Configure the DMA for data reception as needed.

DMA X1 configuration

FMAC DMA X1 configuration

DMA Y configuration

FMAC DMA Y configuration

NVIC configuration

Configure the NVIC in case of an interrupt.

FMAC NVIC configuration

Generated FMAC initialization and de-initialization sequence

The FMAC initialization and de-initialization sequences are generated in the mx_fmac_init and mx_fmac_deinit functions in mx_fmac.c file under $YOUR_PROJECT_NAME$/$YOUR_PROJECT_NAME$_SW/generated/STM32Cube_CodeGen.

STM32CubeMX2 Generated : FMAC initialization sequence

Topic

HAL1

HAL2

Initialization and configuration sequence

static void MX_FMAC_Init(void)
{
  LL_DMA_InitTypeDef DMA_InitStruct = {0};

  /* Peripheral clock enable */
  LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_FMAC);

  /* FMAC DMA Init */

  /* GPDMA1_REQUEST_FMAC_READ Init */
  DMA_InitStruct.SrcAddress = 0x00000000U;
  DMA_InitStruct.DestAddress = 0x00000000U;
  DMA_InitStruct.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
  DMA_InitStruct.BlkHWRequest = LL_DMA_HWREQUEST_SINGLEBURST;
  DMA_InitStruct.DataAlignment = LL_DMA_DATA_ALIGN_ZEROPADD;
  DMA_InitStruct.SrcBurstLength = 1;
  DMA_InitStruct.DestBurstLength = 1;
  DMA_InitStruct.SrcDataWidth = LL_DMA_SRC_DATAWIDTH_BYTE;
  DMA_InitStruct.DestDataWidth = LL_DMA_DEST_DATAWIDTH_BYTE;
  DMA_InitStruct.SrcIncMode = LL_DMA_SRC_FIXED;
  DMA_InitStruct.DestIncMode = LL_DMA_DEST_FIXED;
  DMA_InitStruct.Priority = LL_DMA_LOW_PRIORITY_LOW_WEIGHT;
  DMA_InitStruct.BlkDataLength = 0x00000000U;
  DMA_InitStruct.TriggerMode = LL_DMA_TRIGM_BLK_TRANSFER;
  DMA_InitStruct.TriggerPolarity = LL_DMA_TRIG_POLARITY_MASKED;
  DMA_InitStruct.TriggerSelection = 0x00000000U;
  DMA_InitStruct.Request = LL_GPDMA1_REQUEST_FMAC_READ;
  DMA_InitStruct.TransferEventMode = LL_DMA_TCEM_BLK_TRANSFER;
  DMA_InitStruct.SrcAllocatedPort = LL_DMA_SRC_ALLOCATED_PORT0;
  DMA_InitStruct.DestAllocatedPort = LL_DMA_DEST_ALLOCATED_PORT0;
  DMA_InitStruct.LinkAllocatedPort = LL_DMA_LINK_ALLOCATED_PORT1;
  DMA_InitStruct.LinkStepMode = LL_DMA_LSM_FULL_EXECUTION;
  DMA_InitStruct.LinkedListBaseAddr = 0x00000000U;
  DMA_InitStruct.LinkedListAddrOffset = 0x00000000U;
  LL_DMA_Init(GPDMA1, LL_DMA_CHANNEL_1, &DMA_InitStruct);

  /* GPDMA1_REQUEST_FMAC_WRITE Init */
  DMA_InitStruct.SrcAddress = 0x00000000U;
  DMA_InitStruct.DestAddress = 0x00000000U;
  DMA_InitStruct.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
  DMA_InitStruct.BlkHWRequest = LL_DMA_HWREQUEST_SINGLEBURST;
  DMA_InitStruct.DataAlignment = LL_DMA_DATA_ALIGN_ZEROPADD;
  DMA_InitStruct.SrcBurstLength = 1;
  DMA_InitStruct.DestBurstLength = 1;
  DMA_InitStruct.SrcDataWidth = LL_DMA_SRC_DATAWIDTH_BYTE;
  DMA_InitStruct.DestDataWidth = LL_DMA_DEST_DATAWIDTH_BYTE;
  DMA_InitStruct.SrcIncMode = LL_DMA_SRC_FIXED;
  DMA_InitStruct.DestIncMode = LL_DMA_DEST_FIXED;
  DMA_InitStruct.Priority = LL_DMA_LOW_PRIORITY_LOW_WEIGHT;
  DMA_InitStruct.BlkDataLength = 0x00000000U;
  DMA_InitStruct.TriggerMode = LL_DMA_TRIGM_BLK_TRANSFER;
  DMA_InitStruct.TriggerPolarity = LL_DMA_TRIG_POLARITY_MASKED;
  DMA_InitStruct.TriggerSelection = 0x00000000U;
  DMA_InitStruct.Request = LL_GPDMA1_REQUEST_FMAC_WRITE;
  DMA_InitStruct.TransferEventMode = LL_DMA_TCEM_BLK_TRANSFER;
  DMA_InitStruct.SrcAllocatedPort = LL_DMA_SRC_ALLOCATED_PORT0;
  DMA_InitStruct.DestAllocatedPort = LL_DMA_DEST_ALLOCATED_PORT0;
  DMA_InitStruct.LinkAllocatedPort = LL_DMA_LINK_ALLOCATED_PORT1;
  DMA_InitStruct.LinkStepMode = LL_DMA_LSM_FULL_EXECUTION;
  DMA_InitStruct.LinkedListBaseAddr = 0x00000000U;
  DMA_InitStruct.LinkedListAddrOffset = 0x00000000U;
  LL_DMA_Init(GPDMA1, LL_DMA_CHANNEL_0, &DMA_InitStruct);

  /* FMAC interrupt Init */
  NVIC_SetPriority(FMAC_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
  NVIC_EnableIRQ(FMAC_IRQn);
}
FMAC_TypeDef *mx_fmac_init(void)
{
  LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_FMAC);
  LL_FMAC_SetX1BaseAndSize(FMAC, 0, 0);
  LL_FMAC_SetX2BaseAndSize(FMAC, 0, 0);
  LL_FMAC_SetYBaseAndSize(FMAC, 0, 0);

  /* Configure the DMA Read */

  /* ################################################## FMAC_rd DMA configuration */

  /* Enable GPDMA1 clock */
  LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPDMA1);
  /**********************************************************************************************************************/
  /* LL Optimization Context (DMA) */
  /**********************************************************************************************************************/

  /* Configure DMA channel transfer request */
  LL_DMA_SetPeriphRequest(GPDMA1_CH0, LL_GPDMA1_REQUEST_FMAC_RD);

  /* Configure DMA channel transfer direction */
  LL_DMA_SetDataTransferDirection(GPDMA1_CH0, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);

  /* Configure DMA channel priority level */
  LL_DMA_SetChannelPriorityLevel(GPDMA1_CH0, LL_DMA_PRIORITY_HIGH);

  /* Configure DMA channel transfer register 1 */
  LL_DMA_ConfigTransfer(GPDMA1_CH0,
                        (LL_DMA_SRC_ADDR_FIXED | LL_DMA_SRC_DATA_WIDTH_HALFWORD | \
                         LL_DMA_DEST_ADDR_INCREMENTED | LL_DMA_DEST_DATA_WIDTH_HALFWORD));

  /* Enable the interruption for DMA */
  NVIC_SetPriority(GPDMA1_CH0_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0));
  NVIC_EnableIRQ(GPDMA1_CH0_IRQn);

  return FMAC;
}

Deinitialization sequence

static void MX_FMAC_DeInit(void)
{
 LL_AHB1_GRP1_DisableClock(LL_AHB1_GRP1_PERIPH_FMAC);
        }
void mx_fmac_deinit(void)
{
  LL_FMAC_EnableReset(FMAC);

  LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_FMAC);
  LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_FMAC);

  LL_AHB2_GRP1_DisableClock(LL_AHB2_GRP1_PERIPH_FMAC);

  /* Disable the DMA Read */
  /* De-initialize the DMA channel */
  LL_DMA_DisableChannel(GPDMA1_CH0);
  LL_DMA_ClearFlag(GPDMA1_CH0, LL_DMA_FLAG_ALL);

  LL_DMA_WRITE_REG(GPDMA1_CH0, CCR, 0U);
  LL_DMA_WRITE_REG(GPDMA1_CH0, CTR1, 0U);
  LL_DMA_WRITE_REG(GPDMA1_CH0, CTR2, 0U);
  LL_DMA_WRITE_REG(GPDMA1_CH0, CBR1, 0U);
  LL_DMA_WRITE_REG(GPDMA1_CH0, CTR3, 0U);
  LL_DMA_WRITE_REG(GPDMA1_CH0, CBR2, 0U);
  LL_DMA_WRITE_REG(GPDMA1_CH0, CLLR, 0U);

  /* Disable the interruption for DMA */
  NVIC_DisableIRQ(GPDMA1_CH0_IRQn);
}

Method 2: Replace manually the initialization and de-initialization functions

LL_FMAC_Init() API migration

According to the use-case, implement the precise sequence call based on the LL static inline functions provided in the stm32tnxx_ll_fmac.h header file.

FMAC Mode Comparison between HAL1 and HAL2

HAL1

HAL2

LL_FMAC_Init(FMAC);
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_FMAC);

LL_FMAC_DeInit() API migration

According to the used FMAC, Implement the precise calls to LL_AHB2_GRP1_ForceReset() and LL_AHB2_GRP1_ReleaseReset()

Comparison of HAL1 and HAL2

HAL1

HAL2

LL_FMAC_DeInit(FMAC)
LL_FMAC_EnableReset(FMAC);